package com.koo.modules.purchase.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.koo.common.constant.CodeConstant;
import com.koo.common.utils.*;
import com.koo.common.vo.AuditParams;
import com.koo.common.vo.AuditVo;
import com.koo.framework.feign.SystemFeignService;
import com.koo.modules.product.entity.ProductStockEntity;
import com.koo.modules.product.service.ProductStockService;
import com.koo.modules.purchase.dao.PurchasesInboundOrderDao;
import com.koo.modules.purchase.entity.PurchasesInboundOrderDetailEntity;
import com.koo.modules.purchase.entity.PurchasesInboundOrderEntity;
import com.koo.modules.purchase.entity.vo.PurchaseQueryVo;
import com.koo.modules.purchase.service.PurchasesInboundOrderDetailService;
import com.koo.modules.purchase.service.PurchasesInboundOrderService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@Service
public class PurchasesInboundOrderServiceImpl extends ServiceImpl<PurchasesInboundOrderDao, PurchasesInboundOrderEntity> implements PurchasesInboundOrderService {

    @Autowired
    private ProductStockService productStockService;
    @Autowired
    private SystemFeignService systemFeignService;
    @Autowired
    private PurchasesInboundOrderDetailService  purchasesInboundOrderDetailService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {

        QueryWrapper<PurchasesInboundOrderEntity> wrapper = new QueryWrapper<>();
        List<Long> ids = new ArrayList<>();
        boolean isItemQuery = false;

        Object dataForm = params.get("dataForm");
        if (dataForm != null) {
            PurchaseQueryVo queryVo = JSON.parseObject(dataForm + "", PurchaseQueryVo.class);
            String queryDates = queryVo.getQueryDates();
            Integer auditStatus = queryVo.getAuditStatus();
            String key = queryVo.getKey();
            String queryField = queryVo.getQueryField();
            String itemKey = queryVo.getItemKey();
            String queryItemField = queryVo.getQueryItemField();

            if (queryVo != null) {
                //子查询，获取明细ID
                if (MyStrUtil.isNotEmpty(itemKey) && MyStrUtil.isNotEmpty(queryItemField)) {
                    isItemQuery = true;
                    QueryWrapper<PurchasesInboundOrderDetailEntity> itemWrapper = new QueryWrapper<>();
                    itemWrapper.like(queryItemField, itemKey);
                    List<PurchasesInboundOrderDetailEntity> list = purchasesInboundOrderDetailService.list(itemWrapper);
                    if (CollectionUtils.isNotEmpty(list)) {
                        for (PurchasesInboundOrderDetailEntity detailEntity : list) {
                            ids.add(detailEntity.getInboundId());
                        }
                    }
                }
                if (MyStrUtil.isNotEmpty(queryDates)) {
                    String[] queryDateArr = queryDates.split(",");
                    String startDate = queryDateArr[0];
                    String endDate = queryDateArr[1];
                    wrapper.ge(MyStrUtil.isNotEmpty(startDate), "inbound_date", startDate);
                    wrapper.le(MyStrUtil.isNotEmpty(endDate), "inbound_date", endDate);
                }
                wrapper.eq(auditStatus != null, "IFNULL(audit_status, 0)", auditStatus);
                wrapper.like(StringUtils.isNotBlank(queryField) && StringUtils.isNotBlank(key), queryField, key);
            }
        }

        IPage<PurchasesInboundOrderEntity> page = new Query<PurchasesInboundOrderEntity>().getPage(params);
        if (isItemQuery) {
            if(CollectionUtils.isNotEmpty(ids)){
                page = baseMapper.listPage(page, wrapper, ids);
            }
        } else {
            page = baseMapper.selectPage(page, wrapper);
        }
        return new PageUtils(page);
    }

    @Override
    public List<PurchasesInboundOrderEntity> listByStoreId(Long storeId) {
        LambdaQueryWrapper<PurchasesInboundOrderEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(MyStrUtil.isNotEmpty(storeId), PurchasesInboundOrderEntity::getStoreId, storeId);
        return this.list(wrapper);
    }

    @Override
    public void audit(AuditParams auditParams) {
        //1、修改表单审核状态
        if (auditParams != null && MyStrUtil.isNotEmpty(auditParams.getIds())) {
            String ids = auditParams.getIds();
            String[] idArr = ids.split(",");
            for (int i = 0; i < idArr.length; i++) {
                String id = idArr[i];
                PurchasesInboundOrderEntity orderEntity = baseMapper.selectById(id);
                if (orderEntity != null) {
                    orderEntity.setAuditStatus(auditParams.getAuditStatus());
                    orderEntity.setAuditNote(auditParams.getAuditOptions());
                    baseMapper.updateById(orderEntity);
                }

                //2.插入数据到库存表
                List<PurchasesInboundOrderDetailEntity> detailEntities = purchasesInboundOrderDetailService.listByInBoundId(id);
                if (CollectionUtils.isNotEmpty(detailEntities)) {
                    detailEntities.stream().forEach(item -> {
                        ProductStockEntity stockEntity = new ProductStockEntity();
                        BeanUtils.copyProperties(item, stockEntity);
                        stockEntity.setReceiveNo(orderEntity.getReceiveNo());
                        stockEntity.setReceiveId(orderEntity.getReceiveId());
                        stockEntity.setInboundNo(orderEntity.getInboundNo());
                        stockEntity.setInboundId(orderEntity.getInboundId());
                        stockEntity.setLotNo(CodeConstant.LOT + MyDateUtil.format(new Date(), "yyyyMMddHHmmss"));
                        stockEntity.setPurchasePrice(item.getPurchasePrice());
                        stockEntity.setStockNum(item.getPurchaseCount().longValue());
                        stockEntity.setPurchaseNum(item.getPurchaseCount().longValue());
                        stockEntity.setExpiryDate(MyDateUtil.stringToDate(item.getExpiryDate(), MyDateUtil.DATE_PATTERN));
                        productStockService.save(stockEntity);

                        item.setStockId(stockEntity.getStockId());
                        purchasesInboundOrderDetailService.updateById(item);
                    });
                }
            }

            //3、修改审核表状态
            auditParams.setTitle(auditParams.getAuditStatus() == 1 ? "已审核采购订单" : "审核不通过采购订单");
            String s = systemFeignService.updateAudit(auditParams);
            log.info("updateAudit result===", s);
        }
    }

    @Override
    public String getOrderNo() {
        return CodeConstant.RK + UserUtils.getStoreCode() + MyDateUtil.format(new Date(), "yyyyMMddHHmmss");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveOrder(PurchasesInboundOrderEntity orderEntity) {
        int res = baseMapper.insert(orderEntity);

        this.saveItemList(orderEntity);

        //创建审核单
        Long inboundId = orderEntity.getInboundId();

        AuditVo auditVo = new AuditVo();
        auditVo.setAuditStatus(0);
        auditVo.setUserId(orderEntity.getAuditUserId() + "");
        auditVo.setUserName(orderEntity.getAuditUser());
        auditVo.setOrderId(inboundId);
        auditVo.setOrderNo(orderEntity.getInboundNo());
        auditVo.setTableName("purchases_inbound_order");
        auditVo.setTitle("请审批采购入库单【" + orderEntity.getInboundNo() + "】");
        String s = systemFeignService.saveAduit(auditVo);
        log.info("saveOrder result===", s);
    }

    @Override
    public void saveItemList(PurchasesInboundOrderEntity orderEntity) {
        Long id = orderEntity.getInboundId();
        List<PurchasesInboundOrderDetailEntity> itemList = orderEntity.getItemList();
        if (CollectionUtils.isNotEmpty(itemList)) {
            List<PurchasesInboundOrderDetailEntity> collect = itemList.stream().filter(item -> {
                return MyStrUtil.isNotEmpty(item.getProductCode()) && item.getPurchaseCount().compareTo(new BigDecimal(0)) > 0;
            }).map(item -> {
                item.setInboundDetailId(null);
                item.setInboundId(id);
                item.setInboundNo(orderEntity.getInboundNo());
                return item;
            }).collect(Collectors.toList());
            purchasesInboundOrderDetailService.saveBatch(collect);
        }
    }

    @Override
    public void updateOrder(PurchasesInboundOrderEntity orderEntity) {
        if (orderEntity != null) {
            //1、保存主单
            int res = baseMapper.updateById(orderEntity);
            //2、删除所有明细
            LambdaQueryWrapper<PurchasesInboundOrderDetailEntity> qw = new LambdaQueryWrapper<>();
            qw.eq(orderEntity.getInboundId() != null, PurchasesInboundOrderDetailEntity::getInboundId, orderEntity.getInboundId());
            boolean remove = purchasesInboundOrderDetailService.remove(qw);
            log.info("orderItemService.remove===", remove);
            //3、保存明细
            this.saveItemList(orderEntity);
        }
    }

    @Override
    public PurchasesInboundOrderEntity info(String inboundId) {
        PurchasesInboundOrderEntity inboundOrderEntity = baseMapper.selectById(inboundId);
        List<PurchasesInboundOrderDetailEntity> itemList = purchasesInboundOrderDetailService.list(new LambdaQueryWrapper<PurchasesInboundOrderDetailEntity>().eq(PurchasesInboundOrderDetailEntity::getInboundId, inboundId));
        inboundOrderEntity.setItemList(itemList);
        return inboundOrderEntity;
    }
}